package com.audaque.cloud.iqs.dbs.service.impl;

import com.audaque.cloud.iqs.dbs.Constants;
import com.audaque.cloud.iqs.dbs.DbsUtils;
import com.audaque.cloud.iqs.dbs.enums.DBDataTypeEnum;
import com.audaque.cloud.iqs.dbs.service.DsHandler;
import com.audaque.cloud.iqs.dbs.vo.ColumnInfo;
import com.audaque.cloud.iqs.dbs.vo.DateVo;
import com.audaque.cloud.iqs.dbs.vo.TableInfo;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 达梦DM
 * @author HuangHL
 * @date 2022-10-17 16:50:29
 */
public class DsHandlerMrs implements DsHandler {
    @Override
    public boolean canHander(String driveClass) {
        return driveClass.equals(Constants.HIVE_DRIVER);
    }

    @Override
    public String getTablesSql(String scheme,String user) {
        return "show tables in "+scheme;
    }

    @Override
    public String getColumnsSql(String scheme,String user,String tableName) {
        return "desc "+tableName;
    }

    @Override
    public String getSchema(String schema,String database,String username) {
        //return dataSourceDo.getDatabase();
        return null;
    }

    @Override
    public List<TableInfo> listToTables(List<Map<String, Object>> list) {
        return list.stream().map(e -> {
            String tableName = DbsUtils.mapGetIgnoreCase(e, "table_name");
            String tabName = DbsUtils.mapGetIgnoreCase(e, "tab_name");
            String tableComment = DbsUtils.mapGetIgnoreCase(e, "table_comment");
            return new TableInfo(tableName == null ? tabName : tableName, tableComment == null ? "" : tableComment);
        }).collect(Collectors.toList());
    }

    protected String get(Map<String, Object> map, String key) {
        return DbsUtils.mapGetIgnoreCase(map, key);
    }
    @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE")
    @Override
    public List<ColumnInfo> listToColumns(List<Map<String, Object>> list, String tableName) {
        List<ColumnInfo> res = new ArrayList<>();
        String regex = "\\(.*\\)";
        Pattern pattern = Pattern.compile(regex);
        for (Map<String, Object> map:list) {
            String colName = get(map, "col_name");
            String colDesc = get(map, "comment");
            String dataType = get(map, "data_type");
            if(colName.startsWith("#")) {
                break;
            }
            if(dataType == null) {
                break;
            }
            if("NULL".equals(dataType.toUpperCase())) {
                break;
            }
            String length = null;
            String po = null;
            String key = "0";
            String isIfNull = "0";

            Matcher matcher = pattern.matcher(dataType);
            while (matcher.find()) {
                String str = matcher.group(0);
                String[] arr = str.replace("(",  "").replace(")",  "").split(",");
                if (arr.length == 2) {
                    length = arr[0];
                    po =arr[1];
                    break;
                }
            }

            key = "0";
            isIfNull = "0";

            ColumnInfo columnInfo = new ColumnInfo();
            columnInfo.setTableName(tableName);
            columnInfo.setColName(colName);
            columnInfo.setColDesc(colDesc);
            columnInfo.setColType(dataType);
            if(length!=null) {
                columnInfo.setColLength(Long.valueOf(length));
            }
            if(po!=null) {
                columnInfo.setColPrecision(Integer.valueOf(po));
            }
            columnInfo.setKeyFlag(key);
            columnInfo.setNullable(isIfNull);
            columnInfo.setColSeq(Integer.valueOf("1"));
            columnInfo.setColDataType(DBDataTypeEnum.CHAR.getCode());
            if(dataType!=null) {
                if (dataType.toUpperCase().contains("INT")) {
                    columnInfo.setColDataType(DBDataTypeEnum.NUNBER.getCode());
                }
                if (dataType.toUpperCase().contains("STRING")) {
                    columnInfo.setColDataType(DBDataTypeEnum.CHAR.getCode());
                }
                if (dataType.toUpperCase().contains("TIMESTAMP")) {
                    columnInfo.setColDataType(DBDataTypeEnum.DATATIME.getCode());
                }
            }
            res.add(columnInfo);
        }
        return res;
    }

    @Override
    public String getPage(String sql, int pageNo,int pageSize) {
        int offset = (pageNo-1)*pageSize;
        String mysql = sql+" limit "+offset+","+pageSize;
        return mysql;
    }

    @Override
    public String getDateWhereSql(DateVo dateVo) {
        return "from_unixtime(unix_timestamp("+dateVo.getCol()+"),'yyyy-MM-dd')"+dateVo.getWhereTypeStr()+"'"+dateVo.getVal()+"'";
    }

    @Override
    public String prosessAs(String sql) {
        return sql;
    }

    @Override
    public String sqlSpilit() {
        return "`";
    }


}
